home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Celestin Apprentice 5
/
Apprentice-Release5.iso
/
Source Code
/
C++
/
Snippets
/
SuperSplash 1.0d1
/
sources
/
Shell.cp
< prev
next >
Wrap
Text File
|
1995-10-18
|
12KB
|
552 lines
/*
* Shell.cp
*
* SuperSplash
* ^^^^^^^^^^^
* Main shell for application
* © Andrew Nemeth (where applicable), Warrimoo Australia 1994, 1995
* aznemeng@zeta.org.au
*
* File created: 3 Oct 95.
* Modified: 3, 18 Oct 95.
*/
#include "gConstDefines.h" // Global #defines & const's
#include "gVariables.h" // Global variable defn & 'externs'
#include "stdHighLevelApple.h" // Application High-Level AE
#include "AZN_DBUG.H" // debugging utilites
#include "AZN_TSuperSplash.h" // put up & manage Splash screen
#include <AppleEvents.h> // Mac high level AE
#include <AEObjects.h> // mac OSL constants
#include <LowMem.h>
#include <Gestalt.h>
#include <Balloons.h> // Access to System 7 help menu
#include <limits.h> // For LONG_MAX
// FILE DEFINES…
//
// 'stopMask' parameter in '::FlushEvents()'
const short kshZapEvents = 0;
// PROGRAM GLOBALS
//
struct myGlobalStruct * gptrGlobalsRec = NULL;
// FILE GLOBALS
//
static MenuHandle ghMenus[ kMenusInBar ];
static Boolean gboolUpdateMenus;
static RgnHandle ghMouseRgn;
// Globals used to “tune” the performance of MainEventLoop
// (assume we’ll be starting in the foreground)
static unsigned long gulgRunQuantum;
static unsigned long gulgSleepQuantum;
// FILE FUNCTIONS…
//
static void toolBoxInit ( void );
static void assignProgGlobals ( void );
static void menuBarInit ( void );
static void eventLoop ( void );
static void doEvent ( EventRecord * );
static void doMouseDown ( EventRecord * );
static void doMenuChoice ( long );
static void doAppleChoice ( short );
static void doFileChoice ( short );
static void doOptionsChoice ( short );
static void doKeyPress ( EventRecord * );
static void maintainMenus ( Boolean );
static void quitNow ( void );
void main( void )
//
{
OSErr myErr;
long lgFeature;
toolBoxInit();
INIT_DEBUG();
// MUST be system 7!
myErr = ::Gestalt( gestaltSystemVersion, &lgFeature );
if ( myErr == noErr && ( lgFeature < 0x0700 ) )
ExitToShell();
// need QuickTime for JPEG images
myErr = ::Gestalt( gestaltQuickTimeVersion, &lgFeature );
if ( ( myErr == noErr ) && ( lgFeature < 0x0200 ) )
{
::Alert( kresidALRT_QuickTime, NULL );
}
assignProgGlobals();
menuBarInit();
eventLoop();
}
void toolBoxInit( void )
//
// Initialise toolbox and memory
//
{
::InitGraf( &qd.thePort );
::InitFonts( );
::FlushEvents( everyEvent, kshZapEvents );
::InitWindows( );
::TEInit( );
::InitDialogs( 0L );
::InitCursor( );
// cut down on heap fragmentation
::MaxApplZone( );
::MoreMasters( );
::MoreMasters( );
// fire up high leve AE
highLevelEventInit();
}
void assignProgGlobals( void )
//
// A single place to assign all
// program–wide globals
//
{
// create global struct on heap
gptrGlobalsRec = (myGlobalStruct *)::NewPtrClear( sizeof( myGlobalStruct ) );
// Note on the above
// Don't use 'gptrGlobalsRec = new struct myGlobalStruct;' !
// Operator new in ANSI library allocates blocks of
// memory in 65532 byte slabs. As this global will be
// hanging around for the entire program, it is
// much more efficient to only allocate a ptr of
// size 352 bytes (or so).
//
// initialise global values
if ( gptrGlobalsRec )
{
gptrGlobalsRec->boolDone = FALSE;
// event 'tuning' globals
gptrGlobalsRec->foregroundRunQuantum = 0L;
gptrGlobalsRec->foregroundSleepQuantum = GetCaretTime( );
gptrGlobalsRec->backgroundRunQuantum = 0L;
gptrGlobalsRec->backgroundSleepQuantum = LONG_MAX;
}
}
void menuBarInit( void )
//
// Install about menu and then
// zap all items in menubar
//
{
MenuHandle hMenu = NULL;
Handle hMenuBar = NULL;
hMenuBar = ::GetNewMBar( kMenuBar_ID );
ASSERT( hMenuBar != nil );
::SetMenuBar( hMenuBar );
// assign Global MenuHandle Array
for ( short i = kAppleNdx, j = kMApple_ID; i < kMenusInBar ; i++, j++ )
{
ghMenus[ i ] = (MenuHandle)::GetMenu( j );
ASSERT( ghMenus[ i ] != nil );
}
// insert 'About Application' into apple Menu
hMenu = ::GetMHandle( kMApple_ID );
ASSERT( hMenu != nil );
::AddResMenu( hMenu, 'DRVR' );
::DrawMenuBar( );
gboolUpdateMenus = FALSE;
}
void eventLoop( void )
//
// Main event handling loop
//
{
EventRecord erRec;
unsigned long ulgCheckEvents = 0L;
gulgRunQuantum = gptrGlobalsRec->foregroundRunQuantum;
gulgSleepQuantum = gptrGlobalsRec->foregroundSleepQuantum;
ghMouseRgn = nil;
gboolUpdateMenus = TRUE;
gptrGlobalsRec->boolDone = FALSE;
while ( ! gptrGlobalsRec->boolDone )
{
if ( gulgRunQuantum == 0 || ( ::TickCount( ) > ulgCheckEvents ) )
{
ulgCheckEvents = ::TickCount() + gulgRunQuantum;
::WaitNextEvent( everyEvent, &erRec, gulgSleepQuantum, ghMouseRgn );
doEvent( &erRec );
}
}
// final tidy-up prior to exit
quitNow();
}
void doEvent( EventRecord *ptrEventRec )
//
// Events are first dealt with here
// Note: most of these events are processed
// in the individual dialogFilter procedures!
//
{
switch ( ptrEventRec->what )
{
// null events
case nullEvent:
break;
// see 'stdHighLevelApple.cp'
case kHighLevelEvent:
::AEProcessAppleEvent( ptrEventRec );
break;
// key press
case autoKey:
case keyDown:
doKeyPress( ptrEventRec );
break;
// rat press
case mouseDown:
doMouseDown( ptrEventRec );
break;
// not handled
case activateEvt:
case updateEvt:
break;
// disc insertions
case diskEvt:
if ( ptrEventRec->message >> 16 )
{
static Point where = { 50, 50 };
::DIBadMount( where, ptrEventRec->message );
}
break;
// multi-finder foreground/ background
case osEvt:
switch ( ( ptrEventRec->message & osEvtMessageMask ) >> 24 )
{
case mouseMovedMessage:
break;
case suspendResumeMessage:
if ( ptrEventRec->message & resumeFlag )
{
::SetCursor( &qd.arrow );
gulgRunQuantum = gptrGlobalsRec->foregroundRunQuantum;
gulgSleepQuantum = gptrGlobalsRec->foregroundSleepQuantum;
}
else
{
gulgRunQuantum = gptrGlobalsRec->backgroundRunQuantum;
gulgSleepQuantum = gptrGlobalsRec->backgroundSleepQuantum;
}
break;
}
break;
}
// update menus when there's an interesting event
if ( ptrEventRec->what != nullEvent && gboolUpdateMenus )
maintainMenus( TRUE );
}
void doMouseDown( EventRecord *ptrEventRec )
//
// Someone squeezed the rat…
//
{
WindowPtr ptrWindow;
short thePart;
long lgMenuChoice;
thePart = ::FindWindow( ptrEventRec->where, &ptrWindow );
switch( thePart )
{
// menu selected
case inMenuBar:
lgMenuChoice = ::MenuSelect( ptrEventRec->where );
doMenuChoice( lgMenuChoice );
break;
// window dragged about - not handled
case inDrag:
case inContent:
break;
// DA's
case inSysWindow:
::SystemClick( ptrEventRec, ptrWindow );
gboolUpdateMenus = TRUE;
break;
}
}
void doMenuChoice( long lgMenuChoice )
//
// Menu chosen
//
{
short menu;
short shMenuItem;
if ( lgMenuChoice != 0 )
{
// Macros to break 4-byte value into 2 shorts
menu = HiWord( lgMenuChoice );
shMenuItem = LoWord( lgMenuChoice );
switch( menu )
{
case kMApple_ID:
doAppleChoice( shMenuItem );
break;
case kMFile_ID:
doFileChoice( shMenuItem );
break;
case kMOptions_ID:
doOptionsChoice( shMenuItem );
break;
// system 7 Help menu - not handled
case kHMHelpMenuID:
break;
// catch-all escape to quit application
default:
quitNow( );
break;
}
::HiliteMenu( 0 );
}
}
void doAppleChoice( short shMenuItem )
//
// 'About Application' chosen or DA
//
{
MenuHandle appleMenu = NULL;
Str255 accName = { kEmptyString };
short accNumber;
switch ( shMenuItem )
{
case kM_About:
// knockout highlight on apple menu
::FlashMenuBar( kMApple_ID );
::NoteAlert( kresidALRT_About, kNilFilterProc );
gboolUpdateMenus = TRUE;
break;
// existing Apple Menus
default:
appleMenu = ::GetMHandle( kMApple_ID );
::GetItem( appleMenu, shMenuItem, accName );
accNumber = ::OpenDeskAcc( accName );
gboolUpdateMenus = TRUE;
break;
}
}
void doFileChoice( short shMenuItem )
//
// Parse 'File' menu choice
//
{
switch( shMenuItem )
{
// signal ready for quit
case kM_Quit:
default:
gptrGlobalsRec->boolDone = TRUE;
break;
}
}
void doOptionsChoice( short shMenuItem )
//
// Parse 'Options' menu choice
//
{
ConstStr63Param kstr63JPEGName = { "\pIMAGE.jpeg" },
kstr36PICTName = { "\pIMAGE.pict" };
const short kshPICT_Res_ID = 2000;
TSuperSplash * ptrobjSplash = NULL;
Boolean boolSplashSuccess = FALSE;
OSErr myErr = noErr;
// Show-off the three ways of splashing an image
switch( shMenuItem )
{
// Given the name of a JPEG file in the same directory
// as the application, use the image in it as that
// for the splashscreen
//
case kM_Splash_JPEG_file:
ptrobjSplash = new TSuperSplash( kstr63JPEGName );
break;
// Do the same for a PICT file
//
case kM_Splash_PICT_file:
ptrobjSplash = new TSuperSplash( kstr36PICTName );
break;
// Splash a PICT resource located in the
// application's resource fork
//
case kM_Splash_PICT_resource:
ptrobjSplash = new TSuperSplash( kshPICT_Res_ID );
break;
// catch-all in case of stupidity!
default:
quitNow();
break;
}
// get image on screen
boolSplashSuccess = ptrobjSplash->showSplash();
// stall until mouse click
if ( boolSplashSuccess )
{
::SetCursor( &qd.arrow );
while ( ! ::Button() )
NULL;
::FlushEvents( mDownMask, kshZapEvents );
}
else
::SysBeep(1);
// N.B. Failure will happen if:
// 1. TSuperSplash couldn't find the file in question
// 2. Tried to splash a JPEG file & there is no QuickTime installed
// 3. Usual resource or file error (image file corrupted)
// get rid of splash screen
ptrobjSplash->killSplash();
delete ptrobjSplash;
gboolUpdateMenus = TRUE;
}
void doKeyPress( EventRecord *ptrEventRec )
//
// Respond to cmd-'' keypresses
//
{
register char chCharPressed;
chCharPressed = ptrEventRec->message & charCodeMask;
if ( ( ptrEventRec->modifiers & cmdKey ) != 0 )
{
// quit now 'cmd-/' key press
if ( chCharPressed == '/' && ptrEventRec->modifiers & cmdKey )
quitNow( );
else
doMenuChoice( MenuKey( chCharPressed ) );
}
}
void maintainMenus( Boolean boolEnableAll )
//
// Make sure menus reflect
// current state of application
// If 'boolEnableAll' is FALSE, then menubar
// is deactivated
//
{
const short kshDoForAll = 0;
short i;
// Enable/ disable all menu bar headings
//
for ( i = kAppleNdx; i < kMenusInBar ; i++ )
{
if ( boolEnableAll )
::EnableItem( ghMenus[ i ], kshDoForAll );
else
::DisableItem( ghMenus[ i ], kshDoForAll );
}
// enable/ disable individual items
if ( boolEnableAll )
{
// always activate
::EnableItem( ghMenus[ kFileNdx ], kM_Quit );
::EnableItem( ghMenus[ kOptionsNdx ], kM_Splash_JPEG_file );
::EnableItem( ghMenus[ kOptionsNdx ], kM_Splash_PICT_file );
::EnableItem( ghMenus[ kOptionsNdx ], kM_Splash_PICT_resource );
// wait for update!
::InvalMenuBar( );
}
// deactivate mbar NOW!
else
::DrawMenuBar( );
gboolUpdateMenus = FALSE;
}
void quitNow( void )
//
// When the cmd—'/' is pressed,
// things to do before exit
//
{
gptrGlobalsRec->boolDone = TRUE;
}